package concurrency;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * @author Mr.Sun
 * @date 2022年09月06日 11:52
 *
 * 解决哲学家就餐的死锁问题：通过修改循环等待条件，即修改最后一个哲学家先拿走左手边的筷子，再拿走右手边的筷子
 * {args: 5 5 timeout}
 */
public class FixedDiningPhilosopher {

    public static void main(String[] args) throws Exception {
        int ponder = 5;
        if (args.length > 0 ) {
            ponder = Integer.parseInt(args[0]);
        }
        int size = 5;
        if (args.length > 1) {
            size = Integer.parseInt(args[1]);
        }

        ExecutorService exec = Executors.newCachedThreadPool();

        Chopstick[] sticks = new Chopstick[size];
        for (int i = 0; i < size; i++) {
            sticks[i] = new Chopstick();
        }

        for (int i = 0; i < size; i++) {
            // 若不是最后一个哲学家，则都先拿走右手边的筷子
            if (i < (size - 1)) {
                exec.execute(new Philosopher(sticks[i], sticks[(i+1)], i, ponder));
            } else {
                // 最后一个哲学家先拿起左手边的筷子
                exec.execute(new Philosopher(sticks[0], sticks[(i)], i, ponder));
            }
        }

        if (args.length == 3 && args[2].equals("timeout")) {
            TimeUnit.SECONDS.sleep(20);
        } else {
            System.out.println("Press 'Enter' to quit");
            System.in.read();
        }
        exec.shutdownNow();
    }
}
